package com.ylzinfo.jck.util;

import com.lbs.brick.exception.BusinessException;
import com.ylzinfo.esb.bas.EsbResponse;
import com.ylzinfo.esb.client.XMLRequest;
import com.ylzinfo.jck.domain.Ac01;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.util.StringUtils;
import org.xml.sax.InputSource;

import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 对接持卡库相关方法
 **/
public class CkkUtil {
    private static final String ESBURL = "http://10.96.4.139:8001/esb/esbproxy";
    private static final String USERNAME = "rstjxk";
    private static final String PASSWORD = "4343DC4F90B3F7DFC5E7090976BC86EF27B480B4ED485092";
    // 本地测试节点
    private static final String TESTNODE = "350000002";
    // 省端节点
    private static final String PROVINCENODE = "350000000";
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    /**
     * 持卡库人员信息查询
     * @param ac01
     */
    public static LinkedHashMap<String, String> getPerInfoByJck(Ac01 ac01) {
        XMLRequest xmlRequest = new XMLRequest();
        //ESB服务器路径
        xmlRequest.setEsbUrl(ESBURL);
        //ESB访问用户及密码
        xmlRequest.setEsbUserPwd(new String[]{USERNAME, PASSWORD});
        //存放服务参数名的数组
        String[] v_param = {"aac002", "aac003",
                "fileflag", "bwgfbbh", "jylsh", "jyfqjd",
                "jyjsjd", "ywfqjd", "ywlsh", "ywlx", "jylx"
        };
        //存放服务参数值的数组（与参数名对应）
        String[] v_value = {ac01.getAac002(), ac01.getAac003(),
                "0", "V1.0", TESTNODE + getLSH(), TESTNODE,
                PROVINCENODE, TESTNODE, TESTNODE + getLSH(), "016", "1"};
        //服务ID
        xmlRequest.setSvid("SC_QueryPersonInfo_External");
        xmlRequest.setParam(v_param);
        xmlRequest.setParamValue(v_value);
        //发送封装SOAP数据
        EsbResponse esbRsp = xmlRequest.postXmlRequest();
        System.out.println(esbRsp.getResponseData());
        try {
            //解析返回内容
            List<LinkedHashMap<String, String>> analyze = analyze(esbRsp.getResponseData());
            if (analyze != null && !analyze.isEmpty()) {
                if ((ResultEnum.SUCCESS.getCode() + "").equals(analyze.get(0).get("result"))) {
                    return analyze.get(1);
                } else {
                    throw new BusinessException("持卡库人员信息查询失败,失败原因:" + analyze.get(0).get("fhxx"));
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
            throw new BusinessException("解析持卡库人员信息查询返回结果信息失败");
        }
        return new LinkedHashMap<>();
    }

    /**
     * 持卡库人员新增
     * @param ac01
     * @return
     */
    public static String addPersonInfoByJck(Ac01 ac01) {
        XMLRequest xmlRequest = new XMLRequest();
        //ESB服务器路径
        xmlRequest.setEsbUrl(ESBURL);
        //ESB访问用户及密码
        xmlRequest.setEsbUserPwd(new String[]{USERNAME, PASSWORD});
        //存放服务参数名的数组
        String[] v_param = {"aac002", "aac058", "aac147", "aac003", "aac004", "aac006",
                "fileflag", "bwgfbbh", "jylsh", "jyfqjd",
                "jyjsjd", "ywfqjd", "ywlsh", "ywlx", "jylx"
        };
        //存放服务参数值的数组（与参数名对应）
        String[] v_value = {ac01.getAac002(), ac01.getAac058(), ac01.getAac147(), ac01.getAac003(), ac01.getAac004(), ac01.getAac006() + "",
                "0", "V1.0", TESTNODE + getLSH(), TESTNODE,
                PROVINCENODE, TESTNODE, TESTNODE + getLSH(), "001", "1"};
        //服务ID
        xmlRequest.setSvid("SC_AddPersonInfo_External");
        xmlRequest.setParam(v_param);
        xmlRequest.setParamValue(v_value);
        //发送封装SOAP数据
        EsbResponse esbRsp = xmlRequest.postXmlRequest();
        System.out.println(esbRsp.getResponseData());
        try {
            //解析返回内容
            List<LinkedHashMap<String, String>> analyze = analyze(esbRsp.getResponseData());
            if (analyze != null && !analyze.isEmpty()) {
                if ((ResultEnum.SUCCESS.getCode() + "").equals(analyze.get(0).get("result"))) {
                    return analyze.get(1).get("aac998");
                } else {
                    throw new BusinessException("持卡库人员新增失败,失败原因:" + analyze.get(0).get("fhxx"));
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
            throw new BusinessException("解析持卡库人员信息查询返回结果信息失败");
        }
        return "";
    }

    /**
     * 人员信息变更逻辑判断
     **/
    public static void updatePersonInfoByJck(Ac01 ac01, LinkedHashMap<String, String> hashMap) {
        // 关键信息、次关键信息和非关键信息不能同时变更,每次只能变更一类
        String firstChangeData = splicingFirstChangeData(ac01, hashMap);
        String secondChangeData = splicingSecondChangeData(ac01, hashMap);
        String thirdChangeData = splicingThirdChangeData(ac01, hashMap);
        if (!StringUtils.isEmpty(firstChangeData)) {
            doUpdatePersonInfoByJck(ac01, hashMap, firstChangeData);
        }
        if (!StringUtils.isEmpty(secondChangeData)) {
            doUpdatePersonInfoByJck(ac01, hashMap, secondChangeData);
        }
        if (!StringUtils.isEmpty(thirdChangeData)) {
            doUpdatePersonInfoByJck(ac01, hashMap, thirdChangeData);
        }
    }

    /**
     * 人员信息变更
     **/
    public static void doUpdatePersonInfoByJck(Ac01 ac01, LinkedHashMap<String, String> hashMap, String changeData) {
        XMLRequest xmlRequest = new XMLRequest();
        //ESB服务器路径
        xmlRequest.setEsbUrl(ESBURL);
        //ESB访问用户及密码
        xmlRequest.setEsbUserPwd(new String[]{USERNAME, PASSWORD});

        //存放服务参数名的数组
        String[] v_param = {"aac998", "aac002", "infoverno", "changedata",
                "fileflag", "bwgfbbh", "jylsh", "jyfqjd",
                "jyjsjd", "ywfqjd", "ywlsh", "ywlx", "jylx"
        };
        //存放服务参数值的数组（与参数名对应）
        String[] v_value = {ac01.getAac998() + "", ac01.getAac002(), hashMap.get("infoverno"), changeData,
                "0", "V1.0", TESTNODE + getLSH(), TESTNODE,
                PROVINCENODE, TESTNODE, TESTNODE + getLSH(), "002", "1"};
        //服务ID
        xmlRequest.setSvid("SC_UpdatePersonInfo_External");
        xmlRequest.setParam(v_param);
        xmlRequest.setParamValue(v_value);
        //发送封装SOAP数据
        EsbResponse esbRsp = xmlRequest.postXmlRequest();
        System.out.println(esbRsp.getResponseData());
        try {
            //解析返回内容
            List<LinkedHashMap<String, String>> analyze = analyze(esbRsp.getResponseData());
            if (analyze != null && !analyze.isEmpty()) {
                if (!(ResultEnum.SUCCESS.getCode() + "").equals(analyze.get(0).get("result"))) {
                    throw new BusinessException("持卡库人员信息变更失败,失败原因:" + analyze.get(0).get("fhxx"));
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
            throw new BusinessException("解析持卡库人员信息查询返回结果信息失败");
        }
    }

    /**
     * 报文解析
     * @param soapstr 返回的报文
     * @return List<LinkedHashMap < String, String>>
     **/
    public static List<LinkedHashMap<String, String>> analyze(String soapstr) throws DocumentException {
        List<LinkedHashMap<String, String>> list = new ArrayList<>();
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        LinkedHashMap<String, String> map1 = new LinkedHashMap<>();

        if (soapstr != null && soapstr.indexOf("<header>") >= 0 && soapstr.indexOf("</header>") >= 0) {
            String header = soapstr.substring(soapstr.indexOf("<header>"), soapstr.indexOf("</header>") + "</header>".length());
            InputSource in = new InputSource(new StringReader(header));
            in.setEncoding("UTF-8");
            SAXReader reader = new SAXReader();
            Document document = reader.read(in);
            Element root = document.getRootElement();
            List<Element> elements = root.elements();
            for (Iterator<Element> it = elements.iterator(); it.hasNext(); ) {
                Element element = it.next();
                map.put(element.getName(), element.getTextTrim());
            }
            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + "======" + entry.getValue());
            }
            list.add(map);
        }
        int i = 0;
        while (soapstr != null && soapstr.indexOf("<row" + i + ">") >= 0 && soapstr.indexOf("</row" + i + ">") >= 0)
            if (soapstr != null && soapstr.indexOf("<row" + i + ">") >= 0 && soapstr.indexOf("</row" + i + ">") >= 0) {
                String row = soapstr.substring(soapstr.indexOf("<row" + i + ">"), soapstr.indexOf("</row" + i + ">") + ("</row" + i + ">").length());
                i++;
                InputSource in = new InputSource(new StringReader(row));
                in.setEncoding("UTF-8");
                SAXReader reader = new SAXReader();
                Document document = reader.read(in);
                Element root = document.getRootElement();
                List<Element> elements = root.elements();
                for (Iterator<Element> it = elements.iterator(); it.hasNext(); ) {
                    Element element = it.next();
                    map1.put(element.getName(), element.getTextTrim());
                }
                for (Map.Entry<String, String> entry : map1.entrySet()) {
                    System.out.println(entry.getKey() + "======" + entry.getValue());
                }
                list.add(map1);
            }
        System.out.println(list.size());
        return list;
    }

    /**
     * 关键数据
     * 需要修改的数据内容连接而成，格式为:
     * 变更项目1+变更前信息1+变更后信息1
     * 变更项目2+变更前信息2+变更后信息2
     **/
    public static String splicingFirstChangeData(Ac01 ac01, LinkedHashMap<String, String> hashMap) {
        StringBuilder builder = new StringBuilder();
        //社会保障号
        if (!StringUtils.isEmpty(ac01.getAac002()) && !ac01.getAac002().equals(hashMap.get("aac002"))) {
            builder.append("AAC002+").append(hashMap.get("aac002")).append("+").append(ac01.getAac002()).append("||");
        }
        //姓名
        if (!StringUtils.isEmpty(ac01.getAac003()) && !ac01.getAac003().equals(hashMap.get("aac003"))) {
            builder.append("AAC003+").append(hashMap.get("aac003")).append("+").append(ac01.getAac003()).append("||");
        }
        String changeData = builder.toString();
        return StringUtils.isEmpty(changeData) ? changeData : changeData.substring(0, changeData.length() - 2);
    }

    /**
     * 次关键数据
     * 需要修改的数据内容连接而成，格式为:
     * 变更项目1+变更前信息1+变更后信息1
     * 变更项目2+变更前信息2+变更后信息2
     **/
    public static String splicingSecondChangeData(Ac01 ac01, LinkedHashMap<String, String> hashMap) {
        StringBuilder builder = new StringBuilder();
        //生存状态
        if (!StringUtils.isEmpty(ac01.getAac060()) && !ac01.getAac060().equals(hashMap.get("aac060"))) {
            builder.append("AAC060+").append(hashMap.get("aac060")).append("+").append(ac01.getAac060()).append("||");
        }
        //死亡日期
        if (!StringUtils.isEmpty(ac01.getAae138()) && !ac01.getAae138().equals(hashMap.get("aae138"))) {
            builder.append("AAE138+").append(hashMap.get("aae138")).append("+").append(ac01.getAae138()).append("||");
        }
        String changeData = builder.toString();
        return StringUtils.isEmpty(changeData) ? changeData : changeData.substring(0, changeData.length() - 2);
    }

    /**
     * 除关键信息、次关键信息外的其他人员信息项
     * 需要修改的数据内容连接而成，格式为:
     * 变更项目1+变更前信息1+变更后信息1
     * 变更项目2+变更前信息2+变更后信息2
     **/
    public static String splicingThirdChangeData(Ac01 ac01, LinkedHashMap<String, String> hashMap) {
        StringBuilder builder = new StringBuilder();
        //证件类型
        if (!StringUtils.isEmpty(ac01.getAac058()) && !ac01.getAac058().equals(hashMap.get("aac058"))) {
            builder.append("AAC058+").append(hashMap.get("aac058")).append("+").append(ac01.getAac058()).append("||");
        }
        //证件号码
        if (!StringUtils.isEmpty(ac01.getAac147()) && !ac01.getAac147().equals(hashMap.get("aac147"))) {
            builder.append("AAC147+").append(hashMap.get("aac147")).append("+").append(ac01.getAac147()).append("||");
        }
        //证件有效期限
        if (!StringUtils.isEmpty(ac01.getAab099()) && !ac01.getAab099().equals(hashMap.get("aab099"))) {
            builder.append("AAB099+").append(hashMap.get("aab099")).append("+").append(ac01.getAab099()).append("||");
        }
        //性别
        if (!StringUtils.isEmpty(ac01.getAac004()) && !ac01.getAac004().equals(hashMap.get("aac004"))) {
            builder.append("AAC004+").append(hashMap.get("aac004")).append("+").append(ac01.getAac004()).append("||");
        }
        //民族
        if (!StringUtils.isEmpty(ac01.getAac005()) && !ac01.getAac005().equals(hashMap.get("aac005"))) {
            builder.append("AAC005+").append(hashMap.get("aac005")).append("+").append(ac01.getAac005()).append("||");
        }
        //出生日期
        if (!StringUtils.isEmpty(ac01.getAac006()) && !ac01.getAac006().equals(new Integer(hashMap.get("aac006")))) {
            builder.append("AAC006+").append(hashMap.get("aac006")).append("+").append(ac01.getAac006()).append("||");
        }
        //国家/地区代码
        if (!StringUtils.isEmpty(ac01.getAac161()) && !ac01.getAac161().equals(hashMap.get("aac161"))) {
            builder.append("AAC161+").append(hashMap.get("aac161")).append("+").append(ac01.getAac161()).append("||");
        }
        //手机号码
        if (!StringUtils.isEmpty(ac01.getAac067()) && !ac01.getAac067().equals(hashMap.get("aac067"))) {
            builder.append("AAC067+").append(hashMap.get("aac067")).append("+").append(ac01.getAac067()).append("||");
        }
        //固定电话
        if (!StringUtils.isEmpty(ac01.getAae005()) && !ac01.getAae005().equals(hashMap.get("aae005"))) {
            builder.append("AAE005+").append(hashMap.get("aae005")).append("+").append(ac01.getAae005()).append("||");
        }
        //户口所在地地址
        if (!StringUtils.isEmpty(ac01.getAac010()) && !ac01.getAac010().equals(hashMap.get("aac010"))) {
            builder.append("AAC010+").append(hashMap.get("aac010")).append("+").append(ac01.getAac010()).append("||");
        }
        //常住所在地地址
        if (!StringUtils.isEmpty(ac01.getAae006()) && !ac01.getAae006().equals(hashMap.get("aae006"))) {
            builder.append("AAE006+").append(hashMap.get("aae006")).append("+").append(ac01.getAae006()).append("||");
        }
        //常住所在地邮编
        if (!StringUtils.isEmpty(ac01.getAae007()) && !ac01.getAae007().equals(hashMap.get("aae007"))) {
            builder.append("AAE007+").append(hashMap.get("aae007")).append("+").append(ac01.getAae007()).append("||");
        }
        // TODO: 2021/6/8 监护人姓名 监护人证件类型 监护人证件号码
        //职业（工种）
        if (!StringUtils.isEmpty(ac01.getAca111()) && !ac01.getAca111().equals(hashMap.get("aca111"))) {
            builder.append("ACA111+").append(hashMap.get("aca111")).append("+").append(ac01.getAca111()).append("||");
        }
        //人员持卡状态
        if (!StringUtils.isEmpty(ac01.getAac204()) && !ac01.getAac204().equals(hashMap.get("aac204"))) {
            builder.append("AAC204+").append(hashMap.get("aac204")).append("+").append(ac01.getAac204()).append("||");
        }

        //比对标志
        if (!StringUtils.isEmpty(ac01.getAae550()) && !ac01.getAae550().equals(hashMap.get("aae550"))) {
            builder.append("AAE550+").append(hashMap.get("aae550")).append("+").append(ac01.getAae550()).append("||");
        }
        //户籍地行政区划
        if (!StringUtils.isEmpty(ac01.getAac300()) && !ac01.getAac300().equals(hashMap.get("aac300"))) {
            builder.append("AAC300+").append(hashMap.get("aac300")).append("+").append(ac01.getAac300()).append("||");
        }
        //常住地行政区划
        if (!StringUtils.isEmpty(ac01.getAac301()) && !ac01.getAac301().equals(hashMap.get("aac301"))) {
            builder.append("AAC301+").append(hashMap.get("aac301")).append("+").append(ac01.getAac301()).append("||");
        }
        // TODO: 2021/6/8  人员信息版本号
        //户籍性质
        if (!StringUtils.isEmpty(ac01.getAac009()) && !ac01.getAac009().equals(hashMap.get("aac009"))) {
            builder.append("AAC009+").append(hashMap.get("aac009")).append("+").append(ac01.getAac009()).append("||");
        }
        String changeData = builder.toString();
        return StringUtils.isEmpty(changeData) ? changeData : changeData.substring(0, changeData.length() - 2);
    }

    /**
     * 流水号
     **/
    public static String getLSH() {
        return dateFormat.format(new Date());
    }

    /**
     * 私有化构造器
     **/
    private CkkUtil() {
    }

    /**
     * 交易返回结果枚举
     **/
    enum ResultEnum {
        SUCCESS(0, "业务成功"),
        NO_RECORD(2, "查询无记录");

        Integer code;
        String message;

        ResultEnum(Integer code, String message) {
            this.code = code;
            this.message = message;
        }

        public Integer getCode() {
            return code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }
    }

    /**
     * 测试
     **/
    public static void main(String[] args) {
        //人员查询
//        Ac01 ac01 = new Ac01();
//        ac01.setAac002("350621193609150059");
//        ac01.setAac003("谢亚祥");
//        LinkedHashMap<String, String> map = null;
//        try {
//            map = getPerInfoByJck(ac01);
//            System.out.println("aac998:" + map.get("aac998"));
//        } catch (Exception e) {
//            System.out.println("e.getMessage() = " + e.getMessage());
//        }

        //人员新增
//        Ac01 ac01b = new Ac01();
//        ac01b.setAac002("350621193609150059");
//        ac01b.setAac058("01");
//        ac01b.setAac147("350621193609150059");
//        ac01b.setAac003("谢亚祥");
//        ac01b.setAac004("1");
//        ac01b.setAac006(19360915);
//        try {
//            String aac998 = addPersonInfoByJck(ac01b);
//            System.out.println("aac998:" + aac998);
//        } catch (Exception e) {
//            System.out.println("e.getMessage() = " + e.getMessage());
//        }

        //人员变更
//        Ac01 ac01a = new Ac01();
//        ac01a.setAac998(new BigDecimal("100525630739"));
//        ac01a.setAac002("350621193609150059");
//        ac01a.setAae138("19360916");
//        try {
//            updatePersonInfoByJck(ac01a, map);
//            System.out.println("变更成功");
//        } catch (Exception e) {
//            System.out.println("e.getMessage() = " + e.getMessage());
//        }

        //测试人员新增信息
//        Ac01 ac01 = new Ac01();
//        ac01.setAac002("350621193609150059");
//        ac01.setAac003("谢亚祥");
//        ac01.setAae138("19360917");
//        String aac998 = "";
//        LinkedHashMap<String, String> hashMap = CkkUtil.getPerInfoByJck(ac01);
//        //若aac998为空，调用持卡库新增接口返回aac998本地保存再调用变更接口
//        if (hashMap.get("aac998") == null || "".equals(hashMap.get("aac998"))){
//            aac998 = CkkUtil.addPersonInfoByJck(ac01);
//        }else {
//            aac998 = hashMap.get("aac998");
//        }
//        //若aac998不为空，aac998本地保存再调用变更接口
//        ac01.setAac998(new BigDecimal(aac998));
//        hashMap = CkkUtil.getPerInfoByJck(ac01);
//        CkkUtil.updatePersonInfoByJck(ac01,hashMap);

        //测试人员变更信息
//        long start = System.currentTimeMillis();
//        Ac01 ac01 = new Ac01();
//        ac01.setAac002("370828198106025610");
//        ac01.setAac003("于良忠");
//        ac01.setAae138("19360910");
//        ac01.setAac998(new BigDecimal("100525630739"));
//        String aac998 = "";
//        LinkedHashMap<String, String> hashMap;
//        //查询本地是否有aac998 若无
//        if (ac01.getAac998() == null || ac01.getAac998().compareTo(BigDecimal.ZERO) == 0){
//            //调用持卡库查询接口
//            hashMap = CkkUtil.getPerInfoByJck(ac01);
//            //若aac998为空，调用持卡库新增接口返回aac998本地保存再调用变更接口
//            if (hashMap.get("aac998") == null || "".equals(hashMap.get("aac998"))){
//                aac998 = CkkUtil.addPersonInfoByJck(ac01);
//            }else {
//                aac998 = hashMap.get("aac998");
//            }
//            ac01.setAac998(new BigDecimal(aac998));
//        }
//        //本地存在aac998 则调用持卡库变更接口
//        hashMap = CkkUtil.getPerInfoByJck(ac01);
//        CkkUtil.updatePersonInfoByJck(ac01,hashMap);
//        System.out.println("调用总时间:" + (System.currentTimeMillis() - start));

        //初始化所有ac01
        ExecutorService service = Executors.newFixedThreadPool(10);
        List<Ac01> ac01List = new ArrayList<>();
        for (Ac01 ac01 : ac01List) {
            service.execute(() -> {
                //调用持卡库查询接口
                String aac998 = "";
                LinkedHashMap<String, String> hashMap = CkkUtil.getPerInfoByJck(ac01);
                //若aac998为空，调用持卡库新增接口返回aac998本地保存再调用变更接口
                if (hashMap.get("aac998") == null || "".equals(hashMap.get("aac998"))) {
                    aac998 = CkkUtil.addPersonInfoByJck(ac01);
                } else {
                    aac998 = hashMap.get("aac998");
                }
                //若aac998不为空，aac998本地保存再调用变更接口
                ac01.setAac998(Long.parseLong(aac998));
            });
        }
    }
}
